﻿using UnityEngine;
using System.Collections;
using System.Collections.Generic;

public class WindowManager
{
    public const int WinAnimActionNone = 0;
    public const int WinAnimActionHide = 1;
    public const int WinAnimActionDestroy = 2;

    LinkedList<WindowProxy> windows = new LinkedList<WindowProxy>();

    GameObject _winParent;
    public GameObject winParent
    {
        get
        {
            return _winParent;
        }
        set
        {
            _winParent = value;
        }
    }

    int _startDepth = 0;
    public int startDepth
    {
        get
        {
            return _startDepth;
        }
        set
        {
            _startDepth = value;
        }
    }

//    int _windowDepthBegin = 0;
//    public int windowDepthBegin
//    {
//        get
//        {
//            return windowDepthBegin;
//        }
//        set
//        {
//            windowDepthBegin = value;
//        }
//    }

    int _windowDepthCount = 1;
    public int windowDepthCount
    {
        get
        {
            return _windowDepthCount;
        }
        set
        {
            _windowDepthCount = value;
        }
    }

    public WindowProxy GetWindow<T>(bool isLast = true)
    {
        return  GetWindow(typeof(T), isLast);
    }

    public WindowProxy GetWindow(System.Type t, bool isLast = true)
    {
        return GetWindow(t.Name, isLast);
    }

    public WindowProxy GetWindow(string winName, bool isLast = true)
    {
        LinkedList<WindowProxy>.Enumerator e = windows.GetEnumerator();
        WindowProxy lastWindow = null;
        while(e.MoveNext())
        {
            if (e.Current.winName == winName)
            {
                if (!isLast)
                {
                    return e.Current;
                }
                else
                {
                    lastWindow = e.Current;
                }
            }
        }

        return lastWindow;
    }

    public WindowProxy GetCurWindow()
    {
        if(windows.Count > 0)
        {
            return windows.Last.Value;
        }
        return null;
    }

    public WindowProxy GetCurTopShowWindow()
    {
        LinkedListNode<WindowProxy> last = windows.Last;
        while (last != null)
        {
            if (last.Value.isActive)
            {
                return last.Value;
            }
            last = last.Previous;
        }
        return null;
    }

    public WindowProxy ShowWindow<T>(bool hideCurWindow = true, bool isDestory = false)
    {
		return ShowWindow (typeof(T), hideCurWindow, isDestory);
    }

    public WindowProxy ShowWindow(System.Type t, bool hideCurWindow = true, bool isDestory = false)
    {
        return ShowWindow(t.Name, hideCurWindow, isDestory);
    }

    public WindowProxy ShowWindow(string windowName, bool hideCurWindow = true, bool isDestory = false)
	{
//		if (hideCurWindow)
//		{
//			HideCurWindow(isDestory);
//		}

		WindowProxy window = new WindowProxy();
        window.SetPreWindowProxy(this.GetCurWindow());

        if(hideCurWindow)
        {
            window.preWindowAction = WindowManager.WinAnimActionHide;
        }

        if(isDestory)
        {
            window.preWindowAction = WindowManager.WinAnimActionDestroy;
        }
        
        window.winName = windowName;
		window.parentGo = _winParent;
		WindowProxy curWindow = GetCurWindow();
		if (curWindow != null)
		{
			window.depth = curWindow.depth + windowDepthCount;
		}
		else
		{
			window.depth = _startDepth;
		}
		window.parentWinManager = this;
        LinkedListNode<WindowProxy> last = windows.Last;
        if (last != null)
        {
            last.Value.OnTop(false);
        }
		windows.AddLast(window);
		window.isActive = true;

		return window;
	}

    public void HideAllWindowRemainOne(bool isDestroy = true)
    {
        HideAllWindow(isDestroy, 1);
    }

    public void HideAllWindow(bool isDestroy = true, int remainNum = 0)
    {
        int count = windows.Count;
        LinkedListNode<WindowProxy> last = windows.Last;
        while (last != null)
        {
            if (count <= remainNum)
            {
                break;
            }

            HideWindowInterval(last.Value, isDestroy);
            last = last.Previous;
            if (isDestroy)
            {
                windows.RemoveLast();
            }

            count--;
        }

        if(last != null && last.Value != null)
        {
            last.Value.isActive = true;
            last.Value.OnTop(true);
        }
    }

    private void GetTopTwoWindow(out WindowProxy curWindow, out WindowProxy preWindow)
    {
        curWindow = null;
        preWindow = null;
        LinkedListNode<WindowProxy> node = windows.Last;
        if (node != null)
        {
            curWindow = node.Value;
            node = node.Previous;
            if (node != null)
            {
                preWindow = node.Value;
            }
        }
    }

    public void PlayAnimAndHideCurWindow(IUIAnimElem curWindowAnim, bool curForward, IUIAnimElem preWindowAnim, bool preForward, bool isDestory = true)
    {
        PlayAnim(curWindowAnim, curForward, () =>{ HideCurWindow(isDestory);}, preWindowAnim, preForward, null);
    }

    public void PlayAnimAndHidePreWindow(IUIAnimElem curWindowAnim, bool curForward, IUIAnimElem preWindowAnim, bool preForward, int winAction = WinAnimActionHide)
    {
        PlayAnim(curWindowAnim, curForward, () =>{
            if(winAction != WinAnimActionNone)
            {
                HidePreWindow(winAction == WinAnimActionDestroy);
            }
             }, preWindowAnim, preForward, null);
    }

    public void PlayAnim(IUIAnimElem curWindowAnim, bool curForward, System.Action curCallBack, IUIAnimElem preWindowAnim, bool preForward, System.Action preCallBack)
    {
        if(curWindowAnim == null && preWindowAnim == null)
        {
            return;
        }

        WindowProxy curWindow = null;
        WindowProxy preWindow = null;
        GetTopTwoWindow(out curWindow, out preWindow);

        if (curWindow != null)
        {
            curWindow.isActive = true;
            if(curWindowAnim != null)
            {
                curWindow.SetAnim(curWindowAnim, curForward, curCallBack);
            }
        }

        if (preWindow != null)
        {
            preWindow.isActive = true;
            if(preWindowAnim != null)
            {
                preWindow.SetAnim(preWindowAnim, preForward, preCallBack);
            }
        }
    }

    public void HideCurWindow(bool isDestroy = true)
    {
        WindowProxy window = GetCurWindow();
        HideWindow(window, isDestroy);
    }

    public void HidePreWindow(bool isDestroy = true)
    {
        WindowProxy curWindow = null;
        WindowProxy preWindow = null;
        GetTopTwoWindow(out curWindow, out preWindow);
        HideWindow(preWindow, isDestroy);
    }

    public void HideWindow(System.Type t, bool isDestroy = true, bool isLast = true)
    {
        HideWindow(t.Name, isDestroy, isLast);
    }

    public void HideWindow(string winName, bool isDestroy = true, bool isLast = true)
    {
        WindowProxy window = GetWindow(winName, isLast);
        HideWindow(window, isDestroy);
    }

    public void HideWindow(WindowProxy window, bool isDestroy = true)
    {
        HideWindowInterval(window, isDestroy);
        if (isDestroy)
        {
            windows.Remove(window);
            WindowProxy preWindow = GetCurWindow();
            if (preWindow != null)
            {
                preWindow.isActive = true;
            }
        }
    }

    private void HideWindowInterval(WindowProxy window, bool isDestroy)
    {
        if (window == null)
        {
            return;
        }

        if (isDestroy)
        {
            window.Destroy();
        }
        else
        {
            window.isActive = false;
        }
    }
}